#ifndef LBTR_H_
#define LBTR_H_

/* *
 * @Author: Hien Hoang
 * @Version: Nov 25, 2013
 * */

#include <omnetpp.h>
#include "IPv4Address.h"
#include "IPv4Datagram.h"
#include "INotifiable.h"
#include "LBTRPacket_m.h"
#include "IInterfaceTable.h"
#include "BasicBattery.h"
#include "IRoutingTable.h"
#include "NotificationBoard.h"
#include <map>

class LBTR : public cSimpleModule, INotifiable {

    protected:
        NotificationBoard *nb; // Hien Hoang: For notify to other module (ex: applicationlayer)
        IRoutingTable *irt; //Hien Hoang: For proccess with routing table
        IInterfaceTable *ift; //Hien Hoang: For getting interface card
        BasicBattery *bat;  //Hien Hoang: For getting informaiton of battery
        InterfaceEntry *ie; //Hien Hoang: Which interface card are working on
        int depth; //Hien Hoang: My current depth from base station
        IPv4Address baseStationAddr; //Hien Hoang: base station address
        cMessage *maintenanceTimer;
        cMessage *ackTimeoutTimer;
        std::map<IPv4Address, bool> ackList;
        bool isUp;
    public:
        LBTR();
        virtual ~LBTR();
        virtual void initialize(int stage);
        int numInitStages() const {return 5;}
        virtual void handleMessage(cMessage *msg);
        virtual void handleSelfMessage(cMessage *msg);
        virtual void handleSetupPacket(LBTRSetupPacket *pkt, IPv4Address parentAddr);
        virtual void handleBeaconPacket(LBTRBeaconPacket *pkt, IPv4Address srcAddr);
        virtual LBTRSetupPacket *createSetupPacket();
        virtual LBTRBeaconPacket *createBeaconPacket();
        virtual void startMaintenanceTimer();
        virtual void stopMaintenanceTimer();
        virtual void updateRoutingTable(IPv4Address destAddr, IPv4Address gatewayAddr, int metric);
        virtual int calculateMetric(int parentMetric, int depth, double residualBattery);
        virtual IPv4Datagram *createIPv4Datagram(LBTRPacket *pkt, IPv4Address dest, char *name);
        virtual void sendOut(LBTRPacket *pkt, IPv4Address dest, char *name);
        virtual void receiveChangeNotification(int category, const cObject *details);
};


#endif /* LBTR_H_ */
